Multi-Stage Builds
マルチステージビルド
packagejsonのdependenciesとdevDependenciesと似てる感じで、
開発時に必要な内容と、本番?で必要な内容をわけて書く感じ?mrsekut.icon
各FROMから新しいbuild stageが始まる
FROM .. AS ..でstageに名前をつけられる
COPY --from=hogeみたいにして、別stageの成果物を参照できる
code:Dockerfile
FROM golang:1.16 AS builder
WORKDIR /hoge/piyo/
RUN ...
COPY ...
RUN ...
FROM alpine:latest
RUN ...
WORKDIR ...
COPY --from=builder /hoge/piyo/app ./ # builderからcopy
CMD ...
GPT-4.icon
これを利用することで、開発に必要なツールや依存関係をビルドの段階でのみ使い、最終的なイメージには不要なものを含めないことができます。
### 主な特徴と利点
サイズの最適化
Dockerイメージのサイズを劇的に減らすことができます。
開発やビルドのために必要なツール(例えばコンパイラやテストフレームワーク)は最終的なランタイムイメージには不要です
ステージごとの分割
ビルドプロセスを複数の段階に分け、最終的なイメージには必要なファイルだけを含むようにします。
これにより、ランタイムイメージが軽量でセキュアになります。
依存関係の分離
ビルド時の依存関係と実行時の依存関係を分けることで、セキュリティリスクを低減できます。
例
以下に、基本的なMulti-Stage Buildsの例を紹介します。
code:Dockerfile
# 1. ビルドステージ
FROM node:16 AS build-stage
WORKDIR /app
COPY package.json .
RUN npm install
COPY . .
RUN npm run build
# 2. テストステージ
FROM node:16 AS test-stage
WORKDIR /app
COPY --from=build-stage /app .
RUN npm run test
# 3. 本番環境ステージ
FROM nginx:alpine AS prod-stage
COPY --from=build-stage /app/build /usr/share/nginx/html
build-stage:
アプリケーションをビルドするためのステージです。
test-stage:
ビルド済みの成果物を使ってテストを実行します。このステージは、テストのみに使うため、最終的なイメージには含まれません。
prod-stage:
最終的な軽量な本番環境のイメージを作成します。このステージでは、build-stageからビルド済みの成果物だけをコピーし、Nginxにデプロイします。
↑これはあくまでも例で、
ステージ名や、ステージの数は任意に指定できる
buildする例
build-stageだけをビルドする場合:
--target build-stageを指定します。このコマンドで、build-stageまでのビルドのみが実行されます。
$ docker build --target build-stage -t myapp:build .
test-stageまでをビルドする場合:
--target test-stageを指定して、ビルドした後にテストまで実行します。
$ docker build --target test-stage -t myapp:test .
prod-stage(最終ステージ)をビルドする場合:
--targetオプションを指定しないと、全てのステージがビルドされ、最終的なprod-stageがビルドされます。
$ docker build -t myapp:prod .
### 実際の利点
1. **小さいイメージサイズ**: 不要なビルドツールや開発ツールが最終イメージに含まれないため、サイズが大幅に小さくなります。
2. **セキュリティ向上**: 本番イメージには最低限の必要なものしか含まれないため、セキュリティリスクを減らせます。
3. **柔軟なビルド管理**: 複数のステージを使うことで、ビルドやテスト、ランタイム環境を柔軟に管理できます。